﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using BLL.Services.Users;
using Web.Infrastructure.Models;
using CompareAttribute = System.ComponentModel.DataAnnotations.CompareAttribute;
using DependencyResolver = System.Web.Mvc.DependencyResolver;
using IValidatableObject = System.ComponentModel.DataAnnotations.IValidatableObject;

namespace Web.Areas.Admin.Models.Users
{
    public class UserCreateModel : BaseModel, IValidatableObject
    {
        public UserCreateModel(User user)
        {
            ToModel(user, this);
        }

        public UserCreateModel()
        {
            Status = UserStatus.None;
        }

        [Required(ErrorMessage = @"Email is required!")]
        [RegularExpression(@"[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}", ErrorMessage = "Please enter a valid email address.")]
        [StringLength(256, MinimumLength = 3)]
        [Remote("Validate", "Users", "Admin", AdditionalFields = "Login", ErrorMessage = "User with the same email or login already exists.")]
        public string Email { get; set; }

        [Required]
        [Display(Name = "User status")]
        [UIHint("UserStatus")]
        [Range(1, 3, ErrorMessage = "Please select Status.")]
        public UserStatus Status { get; set; }

        [Compare("ConfirmPassword")]
        [DataType(DataType.Password)]
        [Required]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Compare("Password")]
        [Display(Name = "Confirm password")]
        [Required]
        public string ConfirmPassword { get; set; }

        [Display(Name = "Login")]
        [Required]
        [StringLength(256)]
        [Remote("Validate", "Users", "Admin", AdditionalFields = "Email", ErrorMessage = "User with the same email or login already exists.")]
        public string Login { get; set; }
        
        [UIHint("Upload")]
        [Required]
        public string Avatar { get; set; }

        public static explicit operator User(UserCreateModel model)
        {
            var user = new User();
            ToEntity(model, user);
            if (user.RegistrationDate == DateTime.MinValue)
                user.RegistrationDate = DateTime.Now;
            if (!string.IsNullOrWhiteSpace(model.Password) && model.Password.Equals(model.ConfirmPassword))
                user.SetPassword(model.Password);
            return user;
        }

        /// <summary>
        /// Gets the users service.
        /// </summary>
        /// <value>
        /// The users service.
        /// </value>
        protected static IUsersService UsersService
        {
            get
            {
                return DependencyResolver.Current.GetService<IUsersService>();
            }
        }

        /// <summary>
        /// Determines whether the specified object is valid.
        /// </summary>
        /// <param name="validationContext">The validation context.</param>
        /// <returns>
        /// A collection that holds failed-validation information.
        /// </returns>
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            var result = new List<ValidationResult>();
            if (Password != ConfirmPassword)
            {
                result.Add(new ValidationResult("Confirm Password and Password should match"));
            }
            if (!UsersService.ValidateUser(0, Email, Login))
            {
                result.Add(new ValidationResult("User with the same email or login already exists."));
            }
            return result;
        }
    }
}